﻿/*! 
 *  MyMSDN main script v3.2.136
 */
(function ($, window) {
    'use strict';

    var hasOwnProperty = Object.prototype.hasOwnProperty,
        floor = Math.floor,
        min = Math.min;

    // http://msdn.microsoft.com/en-us/library/system.string.format.aspx
    var sprintf = function () {
        if (arguments.length == 0)
            return '';

        var str = arguments[0];
        for (var i = 1; i < arguments.length; i++) {
            var re = new RegExp('\\{' + (i - 1) + '\\}', 'gm');
            str = str.replace(re, arguments[i]);
        }
        return str;
    };

    /**
    * ReplaceAll by Fagner Brack (MIT Licensed)
    * Replaces all occurrences of a substring in a string
    */
    String.prototype.replaceAll = function (token, newToken, ignoreCase) {
        var _token;
        var str = this + "";
        var i = -1;

        if (typeof token === "string") {

            if (ignoreCase) {

                _token = token.toLowerCase();

                while ((
                    i = str.toLowerCase().indexOf(
                        token, i >= 0 ? i + newToken.length : 0
                    )) !== -1
                ) {
                    str = str.substring(0, i) +
                        newToken +
                        str.substring(i + token.length);
                }

            } else {
                return this.split(token).join(newToken);
            }

        }
        return str;
    };

    // IE8 doesn't have console
    var log = window.console ? function () {
        var s = sprintf.apply(null, arguments);
        window.console.log(s);
    } : function () {
    };

    window.onerror = function (msg, url, line) {
        log(msg + " @my.js#" + line);
        return true;
    };
    // http://msdn.microsoft.com/en-us/library/system.string.contains.aspx
    String.prototype.contains = function (keyword) {
        return this.indexOf(keyword) !== -1;
    };
    // http://msdn.microsoft.com/en-us/library/system.linq.enumerable.first.aspx
    Array.prototype.first = function () {
        if (arguments.length === 0) {
            return this[0];
        } else if (typeof arguments[0] === "function") {
            var comparer = arguments[0];
            for (var k in this) {
                if (hasOwnProperty.call(this, k)) {
                    if (comparer(this[k])) {
                        return this[k];
                    }
                }
            }
            throw new Error("No element matches.");
        } else {
            throw new Error("Invalid parameters.");
        }
    };
    // http://msdn.microsoft.com/en-us/library/system.linq.enumerable.select.aspx
    Array.prototype.select = function () {
        if (typeof arguments[0] === "function") {
            var selector = arguments[0];
            var array = [];
            for (var k in this) {
                if (hasOwnProperty.call(this, k)) {
                    array.push(selector(this[k]));
                }
            }
            return array;
        } else {
            throw new Error("Invalid parameters.");
        }
    };

    // GA
    var track = function (keyword) {
        $("#i-ga").get(0).src = "mm/ga/?" + keyword;
    };
    var decorateGA = function (text) {
        return text.toLowerCase().replaceAll(' ', '-');
    };

    var Page = function () {
        this.init = false;
        this.active = false;
        this.width = 967;
    };
    Page.prototype = {
        ui: null,
        trigger: null,
        index: null,
        flip: function () {
            if (!this.init) {
                this.initUI();
                this.init = true;
            }
            this.activate();
        },
        current: function (v) {
            if (arguments.length) {
                this.active = v;
            }
            return this.active;
        },
        deactivate: function () {
            this.ui.hide();
        },
        navigating: function (who) {

            // lifting
            var lifting = this;

            // add or remove class 'current'
            if (this.active) {
                this.trigger.addClass("current");
            } else {
                this.trigger.removeClass("current");
            }

            // animate pages
            var offset = this.index - who;
            if (offset > 0)
                offset = 0;
            offset *= this.width;
            this.ui.show().animate({ marginLeft: offset.toString() + "px" }, function () {
                if (lifting.active) {
                    lifting.current(false);
                    lifting.flip();
                    track(lifting.hash);
                } else {
                    lifting.deactivate();
                }
            });
        }
    };

    var HomePage = function () {
    };
    HomePage.prototype = $.extend(new Page(), {
        hash: "home",
        tab: "t-home",
        activate: function () {
            // check the referral
            if (window.location.hash.contains("referral")) {
                this.expandwin8 = true;
            } else {
                this.expandwin8 = false;
            }
        },
        initUI: function () {

            var _this = this;
            var _locale = "en";
            var _localeName = "English";
            var _familyId = null;
            var _familyName = null;

            var getED2K = function (file) {
                return sprintf("ed2k://|file|{0}|{1}|{2}|/", file.FileName, file.Size, file.eMule);
            };

            var loadFamily = function (familyId, familyName, locale) {

                $.ajax({
                    url: sprintf("mm/svc/family.ashx?id={0}&locale={1}", familyId, locale),
                    error: function () {
                        $("#mmcxt").html("error.");
                    },
                    beforeSend: function () {
                        var buffer = '<span id="file-loading"></span>';
                        $("#mmcxt").html(buffer);

                        // GA
                        track("home/family/" + _locale + "/" + decorateGA(familyName));
                    },
                    success: function (data) {

                        var buffer = '<div id="mm-list">';

                        // header
                        buffer += sprintf(
                            '<div id="mm-navi">' +
                                '<span class="mm-summary">{0} ({1} <span data-lc="v:results"></span>)</span>' +
                                '<span class="mm-sort" data-lc="v:sortBy"></span>' +
                            '</div>',
                            familyName, data.length);

                        // entity
                        for (var i = 0; i < data.length; i++) {
                            var file = data[i];

                            if (file.eMule) {
                                buffer += sprintf(
                                    '<div class="mm-entity">' +
                                        '<div class="mm-header">' +
                                            '<span>{0}</span>' +
                                            '<a href="{1}" data-file="{5}" data-lc="v:download">{8}</a>' +
                                        '</div>' +
                                        '<div class="mm-subtitle">' +
                                            '<span>{2}</span>' +
                                            '<span><span data-lc="v:realeaseDate">{9}</span> {3}</span>' +
                                            '<span>{4}</span>' +
                                            '<a class="show-detail" data-lc="v:details">{10}</a>' +
                                        '</div>' +
                                        '<div class="mm-detail">' +
                                            '<span><b data-lc="v:fileName">{11}</b> <a href="{1}" data-file="{5}">{5}</a></span>' +
                                            '<span><b data-lc="v:size">{12}</b> {6} <span data-lc="v:bytes">{13}</span></span>' +
                                            '<span><b data-lc="v:sha1">{14}</b> {7}</span>' +
                                        '</div>' +
                                    '</div>',
                                    file.Description, getED2K(file), _localeName, file.PostedDate, file.DisplaySize,
                                    file.FileName, file.Size, file.Sha1);
                            } else {
                                buffer += sprintf(
                                    '<div class="mm-entity">' +
                                        '<div class="mm-header">' +
                                            '<span>{0}</span>' +
                                            '<a href="#checksum" data-lc="v:na">{8}</a>' +
                                        '</div>' +
                                        '<div class="mm-subtitle">' +
                                            '<span>{2}</span>' +
                                            '<span><span data-lc="v:realeaseDate">{9}</span> {3}</span>' +
                                            '<span>{4}</span>' +
                                            '<a class="show-detail" data-lc="v:details">{10}</a>' +
                                        '</div>' +
                                        '<div class="mm-detail">' +
                                            '<span><b data-lc="v:fileName">{11}</b> <a href="#checksum">{5}</a></span>' +
                                            '<span><b data-lc="v:size">{12}</b> <span data-lc="v:na"></span></span>' +
                                            '<span><b data-lc="v:sha1">{14}</b> {7}</span>' +
                                        '</div>' +
                                    '</div>',
                                    file.Description, file.eMule, _localeName, file.PostedDate, file.DisplaySize,
                                    file.FileName, file.Size, file.Sha1);
                            }
                        }

                        buffer += '</div>';
                        $("#mmcxt").html(buffer);

                        // binding click event for 'Detail'
                        $("#mmcxt a.show-detail").click(function () {

                            var detailPane = $(this).parent().parent().children().eq(2);

                            if (detailPane.data("show") === undefined) {
                                detailPane.data("show", false);
                            }

                            if (!detailPane.data("show")) {
                                detailPane.show('slow');
                                detailPane.data("show", true);
                            } else {
                                detailPane.hide('slow');
                                detailPane.data("show", false);
                            }
                        });

                        // binding click event for 'N/A' (goto checksum)
                        $("#mmcxt a[href='#checksum']").click(function () {
                            $("#t-checksum").click();
                        }).each(function () {
                            $(this).attr("data-lc", ($(this).attr("data-lc") || "") + ",t:nohash");
                        });

                        // binding click event for 'Download' GA
                        $("#mmcxt a[data-file]").click(function () {
                            var name = $(this).attr("data-file");
                            track("home/download/" + name);
                        });

                        // localize
                        var lcc = window.Locale.instance();
                        var lc = lcc.get();
                        lcc.refresh(lc, $("#mmcxt"));

                    }
                });
            };

            var init = function (data) {

                var buffer = "";
                for (var i = 0; i < data.length; i++) {
                    var cat = data[i];
                    buffer += sprintf('<dt>{0} (<span>{1}</span>)</dt>', cat.Name, cat.Families.length);
                    buffer += "<dd>";

                    for (var j = 0; j < cat.Families.length; j++) {
                        var family = cat.Families[j];
                        buffer += sprintf('<a data-family-id="{0}">{1}</a>',
                            family.FamilyId, family.Name);
                    }

                    buffer += "</dd>";
                }
                $("#product-family").html(buffer);

                //

                $("#product-family dt").click(function () {

                    var $this = $(this);
                    var family_list = $this.next();

                    if (family_list.data("show") === undefined) {
                        family_list.data("show", false);
                    }

                    if (!family_list.data("show")) {
                        $this.addClass("expanded");
                        family_list.show('slow');
                        family_list.data("show", true);
                    } else {
                        $this.removeClass("expanded");
                        family_list.hide('slow');
                        family_list.data("show", false);
                    }
                });

                $("a[data-family-id]").click(function () {

                    var $this = $(this);
                    _familyId = $this.attr("data-family-id");
                    _familyName = $this.html();

                    loadFamily(_familyId, _familyName, _locale);

                    // scroll to top with animation
                    $('html,body').animate({ scrollTop: 0 }, 'slow');
                    return false;
                });

                // search
                $("#search_box").each(function () {

                    var search_box = $(this);

                    search_box.bind("keyup", function () {

                        var keyword = search_box.val();

                        // search
                        $("a[data-family-id]").each(function () {

                            var $this = $(this);
                            $this.show();

                            if (keyword.length &&
                                !$this.html().toLowerCase().contains(keyword.toLowerCase()))
                                $this.hide();
                        });

                        // update count
                        $("#product-family dt").each(function () {

                            var $this = $(this);
                            var family_length = $this.next().children(":visible").size();

                            $this.find("span").html(family_length);
                        });

                        if (keyword.length) {
                            $("#product-family dt").each(function () {

                                // expand all the families
                                var $this = $(this);
                                var family_list = $this.next();

                                $this.addClass("expanded");
                                family_list.show();
                                family_list.data("show", true);
                            });
                        } else {
                            $("#product-family dt").each(function () {

                                // collapse all the families
                                var $this = $(this);
                                var family_list = $this.next();

                                $this.removeClass("expanded");
                                family_list.hide();
                                family_list.data("show", false);
                            });
                        }

                    });
                });

                // lang-filter
                $.ajax({
                    url: "mm/svc/locale.ashx",
                    error: function () {
                        alert("error getting locale");
                    },
                    success: function (locales) {

                        for (var k in locales) {
                            if (hasOwnProperty.call(locales, k)) {
                                $("#lang-menu").append(
                                    sprintf('<li><a data-locale="{0}">{1}</a></li>', k, locales[k]));
                            }
                        }

                        $("#lang-filter").click(function () {
                            $("#lang-form").dialog("open");
                        });

                        $("#lang-menu a").click(function () {
                            //alert($(this).attr("data-locale"));
                            _locale = $(this).attr("data-locale");
                            _localeName = $(this).html();
                            $("#lang-filter").html(_localeName);

                            if (_familyId && _familyName) {
                                loadFamily(_familyId, _familyName, _locale);
                            }

                            $("#lang-form").dialog("close");
                        });

                        $("#lang-form").dialog({
                            autoOpen: false,
                            width: 620,
                            height: 360,
                            modal: true
                        });
                    }
                });

                // flip
                $("#product-loading").hide();
                $("#search, #lang-filter-container, #product-family").show();

                // load win8 if referral
                if (_this.expandwin8) {
                    _this.expandwin8 = false;

                    _locale = "cn";
                    _localeName = "Chinese - Simplified";
                    _familyId = 481;
                    _familyName = "Windows 8";

                    loadFamily(_familyId, _familyName, _locale);
                    //$("#search_box").val("Windows 8").trigger("keyup");
                }
            };

            $.ajax({
                url: "mm/svc/category.ashx",
                error: function () {
                    alert("error getting product list");
                },
                success: init
            });
        }
    });

    var ChecksumPage = function () {
    };
    ChecksumPage.prototype = $.extend(new Page(), {
        hash: "checksum",
        tab: "t-checksum",
        working: false,
        //file: {},
        activate: function () {

        },
        initUI: function () {

            var lifting = this;

            // check silverlight
            if (!document.getElementById("mysl").Content) {
                $("#c-input").hide();
                $("#no-sliverlight").show();
                return;
            }

            var pbar = $("#c-progress"),
                pLabel = $(".progress-label", pbar);

            pbar.progressbar({
                value: false,
                change: function () {
                    var current = pbar.progressbar("option", "value");
                    pLabel.text(current.toString() + "%");
                },
                complete: function () {
                    pLabel.attr("data-lc", "v:check_completed");

                    // localize
                    var lcc = window.Locale.instance();
                    var lc = lcc.get();
                    lcc.refresh(lc, pLabel);

                    lifting.working = false;
                }
            });
        },
        beginCalc: function (name, size) {
            var pbar = $("#c-progress"),
                pLabel = $(".progress-label", pbar);

            $("#c-fake").val(sprintf("{0} ({1} bytes)", name, size));

            $("#c-result").hide();
            pbar.progressbar("option", "value", false).show();
            log("beginCalc");
        },
        updateProgress: function (v) {

            var pbar = $("#c-progress"),
                pLabel = $(".progress-label", pbar);

            pbar.progressbar("option", "value", floor(v * 100));
            //log("updateProgress({0})", v);
        },
        endCalc: function (state, name, sha1, size) {

            // 0 - not found, 1 - existing, 2 - new, 3 - abnormal
            var result = "";
            switch (state) {
                case 0:
                    result = "check_0";
                    name = "N/A";
                    break;
                case 1:
                    result = "check_1";
                    break;
                case 2:
                    result = "check_2";
                    break;
                case 3:
                    result = "check_3";
                    break;
                default:
                    result = "check_e";
            }

            var buffer = sprintf(
                '<h3 data-lc="v:{0}"></h3>' +
                '<span><b data-lc="v:fileName">File Name:</b> {1}</span>' +
                '<span><b data-lc="v:size">Size:</b> {2} <span data-lc="v:bytes"></span></span>' +
                '<span><b data-lc="v:sha1">SHA1:</b> {3}</span>',
                    result, name, size, sha1);

            $("#c-progress").hide("slow");
            $("#c-result").html(buffer);
            
            // localize
            var lcc = window.Locale.instance();
            var lc = lcc.get();
            lcc.refresh(lc, $("#c-result"));
            
            $("#c-result").show("slow");
            
            log("endCalc");
        }
    });

    var AboutPage = function () {
    };
    AboutPage.prototype = $.extend(new Page(), {
        hash: "about",
        tab: "t-about",
        activate: function () {

        },
        initUI: function () {

        }
    });

    var LocalePage = function () {
    };
    LocalePage.prototype = $.extend(new Page(), {
        hash: "locale",
        tab: "t-locale",
        activate: function () {

        },
        initUI: function () {
            $("#s-locale ul.lang-list a").click(function () {
                var lc = $(this).data("lcc");
                window.Locale.instance().set(lc);
                track("change-locale/" + lc);
                Navigator.instance.goback();
            });
        }
    });

    var Navigator = function () {
        this.pages = null;
    };
    Navigator.prototype = {
        checksum: null,
        run: function () {
            // i18n
            var lcc = window.Locale.instance();
            lcc.refresh(lcc.get());

            // create page instances
            this.pages = [new LocalePage(), new HomePage(), new ChecksumPage(), new AboutPage()];

            // navi history, always push home page
            //this._prev = [this.pages[1], this.pages[1]];

            // expose ChecksumPage to silverlight
            this.checksum = this.pages[2];

            // init slide
            this.slide($("#content"), this.pages.select(function (page) {
                return "#" + page.tab;
            }));

            // navigate to default page
            var hash = this.hash();
            var current = this.pages.first(function (page) {
                return page.hash === hash;
            });
            this.navigate(current);
        },
        hash: function () {
            var q = window.location.hash;
            if (q && q.length) {
                var hashes = this.pages.select(function (page) {
                    return page.hash;
                });
                q = q.substr(1);
                if ($.inArray(q, hashes) !== -1) {
                    return q;
                }
            }
            return this.pages[1].hash;
        },
        navigate: function (current) {
            $("#" + current.tab).click();

            //if (this._prev[1].hash !== current.hash) {
            //    this._prev[0] = this._prev[1];
            //    this._prev[1] = current;
            //}
        },
        goback: function () {
            //this.navigate(this._prev[0]);
            this.navigate(this.pages[1]);
        },
        slide: function ($container, controls) {

            var uiList = $container.find(">ul>li");
            if (uiList.size() !== controls.length || controls.length !== this.pages.length)
                throw new Error("slide count dismatch.");

            var lifting = this.pages;

            uiList.each(function (k) {
                var li = $(this);
                var page = lifting[k];
                var trigger = $(controls[k]);

                // bind each other
                li.data("ref", page);
                trigger.data("ref", page);
                page.ui = li;
                page.trigger = trigger;

                // set index
                page.index = k;
            });

            //var pages = $container.find(">ul>li");
            //var tabs = [];

            //var slideCallback = function () {

            //    var page = $(this);
            //    var tab = null;

            //    for (var q in tabs) {
            //        if (hasOwnProperty.call(tabs, q)) {
            //            if (tabs[q].hasClass("current")) {
            //                tab = tabs[q];
            //                break;
            //            }
            //        }
            //    }

            //    var tabIndex = tab.data("index");
            //    var pageIndex = pages.index(page);
            //    if (tabIndex !== pageIndex)
            //        page.hide();
            //};

            //for (var i = 0; i < controls.length; i++) {
            //    var tab = $(controls[i]);
            //    tab.data("index", i);
            //    tabs.push(tab);
            //}

            for (var k in this.pages) {
                if (hasOwnProperty.call(this.pages, k)) {
                    this.pages[k].trigger.click(function () {

                        log("click {0}", this);
                        var tab = $(this);
                        var page = tab.data("ref");

                        // set the page as current navigating one
                        page.current(true);

                        // navigating
                        for (var q in lifting) {
                            if (hasOwnProperty.call(lifting, q)) {
                                lifting[q].navigating(page.index);
                            }
                        }

                        //for (var q in tabs) {
                        //    if (hasOwnProperty.call(tabs, q)) {
                        //        tabs[q].removeClass("current");
                        //    }
                        //}
                        //tab.addClass("current");

                        // set url hash
                        //window.location.hash = "#" + page.hash;

                        //var index = tab.data("index");
                        //for (var j = 0; j < pages.size() ; j++) {

                        //    var offset = -index + j;
                        //    if (offset > 0)
                        //        offset = 0;

                        //    offset *= width;
                        //    pages.eq(j).show().animate({ marginLeft: offset.toString() + "px" }, slideCallback);
                        //}
                    });
                }
            }
            log("end of slide init.");

        }
    };

    // singleton
    Navigator.instance = new Navigator();

    // expose
    window.Navi = Navigator;
})(jQuery, window);

// entry
$(function () {
    Navi.instance.run();

    //GA
    (function (i, s, o, g, r, a, m) {
        i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
            (i[r].q = i[r].q || []).push(arguments);
        }, i[r].l = 1 * new Date(); a = s.createElement(o),
        m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g;
        m.parentNode.insertBefore(a, m);
    })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');

    ga('create', 'UA-11765858-5', 'mymsdn.info');
    ga('send', 'pageview');

    //Baidu Tongji     
    //var bdhm = window._bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
    //document.write(unescape("%3Cscript src='" + bdhm + "hm.baidu.com/h.js%3Faa4065cc78217e2821558c54fa7ca9ca' type='text/javascript'%3E%3C/script%3E"));
});